﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace Greg.WPF.Controls
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class RotatingTickKnob : UserControl
    {
        /// <summary>
        /// Event to handle turning events
        /// </summary>
        public event KnobStartedEventHandler KnobStarted;
        public delegate void KnobStartedEventHandler(Object sender, KnobTurnedEventArgs e);

        public event KnobCompletedEventHandler KnobCompleted;
        public delegate void KnobCompletedEventHandler(Object sender, KnobTurnedEventArgs e);
        
        public event KnobTurnedEventHandler KnobTurned;
        public delegate void KnobTurnedEventHandler(Object sender, KnobTurnedEventArgs e);
        
        public class KnobTurnedEventArgs : EventArgs
        {
            public KnobTurnedEventArgs() : this(0) { }
            public KnobTurnedEventArgs(double value) { this.Value = value; }
            public double Value { get; set; }
            
        }
       
        /// <summary>
        /// State and image data for knob.
        /// </summary>
        
        
        public String KnobNormalImage { get { return knobNormalImage.ToString();}  set { knobNormalImage = new BitmapImage(new Uri(value, UriKind.RelativeOrAbsolute)); } }
        public String KnobDepressedImage { get { return knobDepressedImage.ToString(); } set { knobDepressedImage = new BitmapImage(new Uri(value, UriKind.RelativeOrAbsolute)); } }       
        BitmapImage knobNormalImage;
        BitmapImage knobDepressedImage;

        public double InitialRotation { get; set; }
        RotateTransform KnobRotateTransform;              
        
        public double RotationPerTick { get; set; }
        public double KnobSensitivity { get; set; }
        public int TickCurrentIndex { get; set; }        
        public int TickIndexMinimum { get; set; }
        public int TickIndexMaximum { get; set; }
        public List<double> TickValueList;
        private int TickStateDelta;
 
        public RotatingTickKnob()
        {
            IntializeTicks();
            InitializeComponent();               
        }

        public void IntializeTicks()
        {
            RotationPerTick = 45;
            KnobSensitivity = 1;
            TickCurrentIndex = 0;
            TickStateDelta = 0;
        }

        protected void knob_Loaded(object sender, RoutedEventArgs e)
        {
            if (knobNormalImage == null) knobNormalImage = new BitmapImage(new Uri("knob4a.png", UriKind.RelativeOrAbsolute));
            if (knobDepressedImage == null) knobDepressedImage = new BitmapImage(new Uri("knob4b.png", UriKind.RelativeOrAbsolute));
            KnobRotateTransform = new RotateTransform(InitialRotation);
            KnobRotateTransform.CenterX = knob.ActualHeight / 2;
            KnobRotateTransform.CenterY = knob.ActualWidth / 2;
            knob.RenderTransform = KnobRotateTransform;
            knob.Source = knobNormalImage;
        }
        
        private void myThumb_DragStarted(object sender, DragStartedEventArgs e)
        {           
            knob.Source = knobDepressedImage;
            KnobTurnedEventArgs kte = new KnobTurnedEventArgs(0);
            if (KnobStarted != null) KnobStarted(this, kte);
        }

        private void myThumb_DragCompleted(object sender, DragCompletedEventArgs e)
        {
            knob.Source = knobNormalImage;        
            TickCurrentIndex += TickStateDelta;
     
            if (KnobTurned != null)
            {
                KnobTurnedEventArgs kte = new KnobTurnedEventArgs();
                if (TickValueList != null) kte.Value = TickValueList[TickCurrentIndex];
                else kte.Value = TickCurrentIndex;
                KnobCompleted(this, kte);
            }
        }

        protected void myThumb_DragDelta(object sender, DragDeltaEventArgs e)
        {                      
            int deltaTick = (int)Math.Round((e.VerticalChange*KnobSensitivity) / RotationPerTick);
            int newTickIndex = deltaTick + TickCurrentIndex;
              
                if (deltaTick != TickStateDelta && newTickIndex <= TickIndexMaximum && newTickIndex >= TickIndexMinimum)
                {
                    TickStateDelta = deltaTick;
                    KnobRotateTransform.Angle = newTickIndex * RotationPerTick + InitialRotation;

                    if (KnobTurned != null)
                    {
                        KnobTurnedEventArgs kte = new KnobTurnedEventArgs();
                        if (TickValueList != null) kte.Value = TickValueList[TickCurrentIndex];
                        else kte.Value = TickCurrentIndex;                    
                        KnobTurned(this, kte);
                    }
                }
            
        }    
      
    }
}
